#include "typefactory.h"

using namespace core;

TypeFactory* typeFactory = 0;

TypeFactory* TypeFactory::getInstance()
{
    if (typeFactory == 0)
    {
        typeFactory = new TypeFactory();
    }

    return typeFactory;
}

void TypeFactory::destroy()
{
    delete typeFactory;
    typeFactory = 0;
}

void TypeFactory::registerType(const Type& type)
{
    const TypeName name = type.name();

    Q_ASSERT(!name.isEmpty());

    if (!m_registeredTypes.contains(name))
    {
        m_registeredTypes[name] = type.copy();
        m_registeredKeywordMasks << type.keywordMask();
    }
}

void TypeFactory::unregisterType(const TypeName& name)
{
    Q_ASSERT(!name.isEmpty());

    if (m_registeredTypes.contains(name))
    {
        const Type* type = m_registeredTypes[name];
        m_registeredTypes.remove(name);
        m_registeredKeywordMasks.remove(type->keywordMask());

        delete type;
    }
}

Type const* TypeFactory::getTypeInstance(const TypeName& name)
{
    const Type* ret = 0;

    if (m_registeredTypes.contains(name))
    {
        ret = m_registeredTypes[name];
    }

    return ret;
}

bool TypeFactory::isRegistered(const Type& type)
{
    return m_registeredTypes.contains(type.name());
}

QSet<TypeName> TypeFactory::registeredTypes() const
{
    return m_registeredTypes.keys().toSet();
}

QSet<ValueKeywordMask> TypeFactory::registeredKeywordMasks() const
{
    return m_registeredKeywordMasks;
}

TypeFactory::TypeFactory() :
    m_registeredTypes()
{

}

TypeFactory::~TypeFactory()
{
    foreach (const QString& key, m_registeredTypes.keys())
    {
        const Type* type = m_registeredTypes[key];
        m_registeredTypes.remove(key);

        delete type;
    }
}
